package com.abc.example.service.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.github.pagehelper.PageInfo;
import io.gitee.shengzheng1999.esbcommon.common.impexp.BaseExportObj;
import io.gitee.shengzheng1999.esbcommon.common.impexp.BaseImportObj;
import io.gitee.shengzheng1999.esbcommon.common.impexp.ExcelExportHandler;
import io.gitee.shengzheng1999.esbcommon.common.impexp.ExcelImportHandler;
import io.gitee.shengzheng1999.esbcommon.common.impexp.ImpExpFieldDef;
import io.gitee.shengzheng1999.esbcommon.common.utils.FileUtil;
import io.gitee.shengzheng1999.esbcommon.common.utils.LogUtil;
import io.gitee.shengzheng1999.esbcommon.common.utils.ObjListUtil;
import io.gitee.shengzheng1999.esbcommon.common.utils.ReflectUtil;
import io.gitee.shengzheng1999.esbcommon.common.utils.Utility;
import io.gitee.shengzheng1999.esbcommon.entity.SysParameter;
import com.abc.example.config.UploadConfig;
import com.abc.example.dao.OrgnizationDao;
import com.abc.example.entity.Orgnization;
import com.abc.example.enumeration.EDeleteFlag;
import com.abc.example.enumeration.EDistrictLevel;
import com.abc.example.enumeration.EIdType;   
import com.abc.example.enumeration.EOrgType;
import com.abc.example.exception.BaseException;
import com.abc.example.exception.ExceptionCodes;
import com.abc.example.service.BaseService;
import com.abc.example.service.CacheDataService;
import com.abc.example.service.DataRightsService;
import com.abc.example.service.IdCheckService;
import com.abc.example.service.OrgnizationManService;
import com.abc.example.service.SysParameterService;
import com.abc.example.service.TableCodeConfigService;



/**
 * @className	: OrgnizationManServiceImpl
 * @description	: 组织机构对象管理服务实现类
 * @summary		: 
 * @history		:
 * ------------------------------------------------------------------------------
 * date			version		modifier		remarks
 * ------------------------------------------------------------------------------
 * 2024/01/14	1.0.0		sheng.zheng		初版
 *
 */
@SuppressWarnings({ "unchecked", "unused" })
@Service
public class OrgnizationManServiceImpl extends BaseService implements OrgnizationManService{
	// 组织机构对象数据访问类对象
	@Autowired
	private OrgnizationDao orgnizationDao;

    // 文件上传配置类对象
    @Autowired
    private UploadConfig uploadConfig;

    // 对象ID检查服务类对象
	@Autowired
	private IdCheckService ics;   

	// 缓存数据服务类对象
	@Autowired
	private CacheDataService cds;

	// 数据权限服务类对象
	@Autowired
	private DataRightsService drs;

	// 全局ID服务类对象
	@Autowired
	private TableCodeConfigService tccs;
    
    // 系统参数服务类对象
	@Autowired
	private SysParameterService sps;

    // 主键属性名
    private String[] keyFields = new String[]{"orgId"};    
    private String keyPropName = "orgId";

    // 对象外键相关属性名数组
    private String[] refKeyFields = new String[]{"parentId"};  

    // 数据权限相关属性名数组
    private String[] drFields = new String[]{"orgId"};
    private String[] refDrFields = new String[]{"parentId"};            

    // 枚举值相关属性名数组
    private String[] enumFields = new String[]{"orgType","districtLevel"};

    // 唯一键相关属性名数组
    private String[] uniqueFields = new String[]{"orgName"};


	/**
	 * @methodName		: addItem
	 * @description		: 新增一个组织机构对象
	 * @see {@link OrgnizationManService#addItem}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
	@Override
	public Map<String,Object> addItem(HttpServletRequest request, Orgnization item) {
		// 检查输入参数：必选字段是否有值
		checkValidForParams(request, "addItem", item);

        // 检查外键属性值      
        checkRefKeys(item,refKeyFields);

        // 检查数据权限
        if (request != null){
            // 非内部调用
            drs.checkDataRights(request, item, refDrFields, drFields);
        }

        // 检查枚举值
        checkEnums(item, enumFields);

        // 检查唯一性
        checkUniques(item, uniqueFields);

        Integer orgId = 0;
		// 获取全局记录ID
		Long globalRecId = tccs.getTableRecId("exa_orgnizations");
		orgId = globalRecId.intValue();

		// 获取操作人账号
		String operatorName = getUserName(request);

		// 设置信息
		item.setOrgId(orgId);
		item.setOperatorName(operatorName);
		
		try {
    		// 插入数据
			orgnizationDao.insertItem(item);
			
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.ADD_OBJECT_FAILED, item.toString() + ":" + e.getMessage());
		}
		
		// 构造返回值
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("orgId", orgId);
		
		return map;
	}

	/**
	 * @methodName		: addItems
	 * @description		: 批量新增组织机构对象
	 * @see {@link OrgnizationManService#addItems}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
	@Override
	public Map<String,Object> addItems(HttpServletRequest request, List<Orgnization> itemList) { 
		// 输入参数校验
		checkValidForParams(request, "addItems", itemList);
		
		if (itemList.size() == 0) {
			throw new BaseException(ExceptionCodes.ARGUMENTS_IS_EMPTY,"itemList");
		}

        // 检查列表是否有重复唯一key
        Map<String,Integer> fieldMap = new HashMap<String,Integer>();
        fieldMap.put("orgName",1);
        checkDuplicates(itemList,fieldMap,true);

        // 检查参数一致性
        String[] sameFields = new String[]{"parentId"};
        checkSames(itemList,sameFields);

        // 检查外键属性值       
        checkRefKeys(itemList,refKeyFields);

        // 检查数据权限
        if (request != null){
            // 非内部调用
            drs.checkDataRights(request, itemList, refDrFields, drFields);
        }

        // 检查枚举值
        checkEnums(itemList, enumFields);

        // 检查唯一性
        checkUniques(itemList, uniqueFields);

		// 获取操作人账号
		String operatorName = getUserName(request);

        Integer orgId = 0;
		// 获取全局记录ID
		Long globalRecId = tccs.getTableRecIds("exa_orgnizations", itemList.size());
		orgId = globalRecId.intValue();

		// 设置信息
		for(int i = 0; i < itemList.size(); i++) {
			Orgnization item = itemList.get(i);
            item.setOrgId(orgId + i);
			item.setOperatorName(operatorName);
		}
		
		try {
    		// 插入数据
            orgnizationDao.insertItems(itemList);
			
			 // 可能的数据库一致性处理			
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.ADD_OBJECT_FAILED, e.getMessage());
		}
		
		// 构造返回值
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("orgId", orgId);
		
		return map;
	}

	/**
	 * @methodName		: editItem
	 * @description		: 根据key修改一个组织机构对象
	 * @see {@link OrgnizationManService#editItem}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
	@Override
	public void editItem(HttpServletRequest request, Map<String, Object> params) {
		// 输入参数校验
		checkValidForParams(request, "editItem", params);
		
        // 检查主键并获取对象
        Orgnization oldItem = (Orgnization)checkKeys(params,keyPropName);

        // 检查外键属性值      
        checkRefKeys(params, oldItem, refKeyFields);

        // 检查数据权限
        if (request != null){
            // 非内部调用
            drs.checkDataRights(request, params, refDrFields, drFields);
            drs.checkDataRights(request, oldItem, drFields);
        }

        // 检查枚举值
        checkEnums(params, enumFields);

        // 检查唯一性
        checkUniques(params, oldItem, uniqueFields);

        // 对参数进行过滤，防止其它参数值干扰导致记录损坏，只选取主键和可编辑项
        Map<String, Object> dbParams = new HashMap<String, Object>();
		// 获取操作人账号
		String operatorName = getUserName(request);
		// 设置信息
		dbParams.put("operatorName", operatorName);

        // 添加key字段
        Utility.addKeys(dbParams, params, keyFields);        
        // 添加可编辑的项
        String[] editFields =  new String[]{"orgCode","orgName","orgFullname","orgType",
        	"orgCategory","leader","contacts","phoneNumber","email","address","zipcode","district",
        	"districtLevel","parentId","lon","lat","remark"};        
        Utility.addKeys(dbParams, params, editFields);

		try {
		    // 修改数据
			orgnizationDao.updateItemByKey(dbParams);
			
			 // 可能的数据库一致性处理			
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.UPDATE_OBJECT_FAILED, dbParams.toString() + ":" + e.getMessage());
		}
		// 缓存处理
		cds.removeItem("Orgnization", oldItem.getObjKey());        
	}

	/**
	 * @methodName		: updateItems
	 * @description		: 根据条件批量修改组织机构对象
	 * @see {@link OrgnizationManService#updateItems}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */       
	@Override
	public void updateItems(HttpServletRequest request, Map<String, Object> params) {
		// 输入参数校验
		checkValidForParams(request, "updateItems", params);

        // 检查至少包含一个修改字段
        String[] setFields = new String[] {"zipcode","district","districtLevel","remark"};
        Utility.checkOpKeyFields(params,setFields);

        // 检查至少包含一个条件字段
        String[] condFields = new String[] {"parentId","orgIdList"};
        Utility.checkOpKeyFields(params,condFields);  

        // 检查外键属性值      
        checkRefKeys(params, refKeyFields);

        // 检查数据权限
        if(request != null){
            drs.checkDataRights(request, params, refDrFields, drFields);
            List<Integer> orgIdList = drs.getQueryDrList(request,"orgId");
            if (params.containsKey("orgIdList")){
                List<Integer> orgIdList2 = (List<Integer>)params.get("orgIdList"); 
                orgIdList = drs.mergeDrIdList(orgIdList,orgIdList2);
                params.put("orgIdList",orgIdList);
            }
        }

        // 检查枚举值
        checkEnums(params, enumFields);

        // 先查询修改可能受影响的记录列表，这些记录对象需要更新缓存
        Map<String,Object> dbParams = new HashMap<String,Object>();
        // 复制请求参数字典
        for(String key : params.keySet()){
            dbParams.put(key,params.get(key));
        }        
        // 只保留条件字段
        Utility.removeKeys(dbParams,setFields);
        List<Orgnization> itemList = orgnizationDao.selectItems(dbParams);
        List<Integer> orgIdList = ObjListUtil.getSubFieldList(itemList,"orgId");
		// 获取操作人账号
		String operatorName = getUserName(request);
		// 设置信息
		params.put("operatorName", operatorName);

		try {
    		// 修改数据
			orgnizationDao.updateItems(params);
			
			 // 可能的数据库一致性处理			
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.UPDATE_OBJECT_FAILED, params.toString() + ":" + e.getMessage());
		}		

		// 缓存处理
        for(Integer key : orgIdList){
		    cds.removeItem("Orgnization", key);        
        }
	}    

	/**
	 * @methodName		: deleteItem
	 * @description		: 根据key禁用/启用一个组织机构对象
	 * @see {@link OrgnizationManService#deleteItem}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
	@Override
	public void deleteItem(HttpServletRequest request, Map<String, Object> params) {
		// 输入参数校验
		checkValidForParams(request, "deleteItem", params);
		
        // 检查主键并获取对象
        Orgnization oldItem = (Orgnization)checkKeys(params,keyPropName);

        // 检查数据权限
        if (request != null){
            // 非内部调用
            drs.checkDataRights(request, oldItem, drFields);
        }

		// 检查删除标记
		Integer deleteFlag = (Integer)params.get("deleteFlag");
		if (deleteFlag == null) {
			// 默认为停用
			deleteFlag = EDeleteFlag.dfDeletedE.getCode();
		}
		if (oldItem.getDeleteFlag() == deleteFlag.byteValue()) {
			// 不变
			return;
		}

        // 另建字典，防止params携带其它参数
        Map<String, Object> dbParams = new HashMap<String, Object>();
        // 添加key字段
        Utility.addKeys(dbParams, params, keyFields); 
        dbParams.put("deleteFlag",deleteFlag.byteValue());        
		// 获取操作人账号
		String operatorName = getUserName(request);
		// 设置信息
		dbParams.put("operatorName", operatorName);

		try {
    		// 修改数据
			orgnizationDao.updateItemByKey(dbParams);
			
			 // 可能的数据库一致性处理			
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.UPDATE_OBJECT_FAILED, dbParams.toString() + ":" + e.getMessage());
		}		
		// 缓存处理
		cds.removeItem("Orgnization", oldItem.getObjKey());        
	}

	/**
	 * @methodName		: deleteItems
	 * @description		: 根据条件批量删除组织机构对象
	 * @see {@link OrgnizationManService#deleteItems}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */    
	@Override
	public void deleteItems(HttpServletRequest request, Map<String, Object> params) {
		// 输入参数校验
		checkValidForParams(request, "deleteItems", params);

        // 检查至少包含一个条件字段
        String[] condFields = new String[] {"orgIdList","parentId"};
        Utility.checkOpKeyFields(params,condFields);  

        // 检查数据权限
        if (request != null){
            drs.checkDataRights(request, params, refDrFields, drFields);
            List<Integer> orgIdList = drs.getQueryDrList(request,"orgId");
            if (params.containsKey("orgIdList")){
                List<Integer> orgIdList2 = (List<Integer>)params.get("orgIdList"); 
                orgIdList = drs.mergeDrIdList(orgIdList,orgIdList2);
                params.put("orgIdList",orgIdList);
            }
        }

        // 先查询操作可能受影响的记录列表，这些记录对象需要更新缓存
        List<Orgnization> itemList = orgnizationDao.selectItems(params);
        List<Integer> orgIdList = ObjListUtil.getSubFieldList(itemList,"orgId");

        // 另建参数字段，防止params携带其它参数
        Map<String,Object> dbParams = new HashMap<String,Object>(); 
        // 添加条件字段
        Utility.addKeys(dbParams, params, condFields); 

        dbParams.put("deleteFlag", (byte)EDeleteFlag.dfDeletedE.getCode());
		// 获取操作人账号
		String operatorName = getUserName(request);
		// 设置信息
		dbParams.put("operatorName", operatorName);

		try {
    		// 修改数据
			orgnizationDao.updateItems(dbParams);
			
			 // 可能的数据库一致性处理			
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.UPDATE_OBJECT_FAILED, dbParams.toString() + ":" + e.getMessage());
		}

		// 缓存处理
        for(Integer key : orgIdList){
		    cds.removeItem("Orgnization", key);        
        }
	}

	/**
	 * @methodName		: queryItems
	 * @description		: 根据条件分页查询组织机构对象列表
	 * @see {@link OrgnizationManService#queryItems}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
	@Override
	public PageInfo<Orgnization> queryItems(HttpServletRequest request,
			 Map<String, Object> params) {
		PageInfo<Orgnization> pageInfo = null;
        if (request != null) {
            List<Integer> orgIdList = drs.getQueryDrList(request,"orgId");
            if (params.containsKey("orgIdList")){
                List<Integer> orgIdList2 = (List<Integer>)params.get("orgIdList"); 
                orgIdList = drs.mergeDrIdList(orgIdList,orgIdList2);
                params.put("orgIdList",orgIdList);
            }
        }

		try {
    		// 查询数据
			// 分页处理
			processPageInfo(params);
			// 查询记录
			List<Orgnization> itemList = orgnizationDao.selectItems(params);

			// 分页对象
			pageInfo = new PageInfo<Orgnization>(itemList);
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.QUERY_OBJECT_FAILED, params.toString() + ":" + e.getMessage());
		}
		
		return pageInfo;
	}

	/**
	 * @methodName		: getItem
	 * @description		: 根据key获取一个组织机构对象
	 * @see {@link OrgnizationManService#getItem}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
	@Override
	public Orgnization getItem(HttpServletRequest request, Map<String, Object> params) {
		// 输入参数校验
		checkValidForParams(request, "getItem", params);
		
        Orgnization item = null;
        Integer orgId = Integer.valueOf(params.get("orgId").toString());
		
		try {
			// 查询记录
			item = orgnizationDao.selectItemByKey(orgId);

            if (item != null){
                // 检查数据权限
                if (request != null){
                    // 非内部调用
                    drs.checkDataRights(request, item, drFields);
                }
            }        
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.QUERY_OBJECT_FAILED, params.toString() + ":" + e.getMessage());
		}

    	return item;
	}

	/**
	 * @methodName		: getItems
	 * @description		: 根据条件查询组织机构对象列表
	 * @see {@link OrgnizationManService#getItems}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
	@Override
	public List<Orgnization> getItems(HttpServletRequest request,
			 Map<String, Object> params) {
        if (request != null) {
            List<Integer> orgIdList = drs.getQueryDrList(request,"orgId");
            if (params.containsKey("orgIdList")){
                List<Integer> orgIdList2 = (List<Integer>)params.get("orgIdList"); 
                orgIdList = drs.mergeDrIdList(orgIdList,orgIdList2);
                params.put("orgIdList",orgIdList);
            }
        }

		try {
			// 查询记录
			List<Orgnization> itemList = orgnizationDao.selectItems(params);
			return itemList;
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.QUERY_OBJECT_FAILED, params.toString() + ":" + e.getMessage());
		}
	}

	/**
	 * 
	 * @methodName		: insertItems
	 * @description	    : 批量插入组织机构对象记录，用于内部调用，调用处应保证数据的有效性
	 * @see {@link OrgnizationManService#insertItems}
	 * @history		    : 
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks                   
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
    @Override
	public void insertItems(List<Orgnization> itemList){
		// 获取全局记录ID
		Long globalRecId = tccs.getTableRecIds("exa_orgnizations", itemList.size());
		Integer orgId = globalRecId.intValue();

		// 设置key
		for(int i = 0; i < itemList.size(); i++) {
			Orgnization item = itemList.get(i);
            item.setOrgId(orgId + i);
		}

		try {
    		// 插入数据
            orgnizationDao.insertItems(itemList);
			
			 // 可能的数据库一致性处理			
		} catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.ADD_OBJECT_FAILED,e.getMessage());
		}             
    }

	/**
	 * 
	 * @methodName		: flushItem
	 * @description	    : 对象存在则修改，否则新增，用于内部调用
	 * @see {@link OrgnizationManService#flushItem}
	 * @history		    : 
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks                   
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
    @Override
	public void flushItem(HttpServletRequest request,Orgnization item,List<String> editFields){
        // 先查询对象是否存在
        Orgnization oldItem = null;
        String orgName = item.getOrgName();
        oldItem = orgnizationDao.selectItemByOrgName(orgName);

        if (oldItem == null){
            // 对象不存在，则新增
            addItem(request,item);
        }else{
            // 对象已存在，则修改
            // 比较修改字段的值是否有变化
            boolean bSame = ReflectUtil.hasSameSubPropValues(item,oldItem,editFields);
            if (!bSame) {
                // 如果与原对象有属性值不同，则修改记录
                Map<String,Object> params = ReflectUtil.getValuesMap(item,editFields);
                // 设置key值
                params.put("orgId",oldItem.getOrgId());
                editItem(request,params);
            }
        }
    }    

	/**
	 * 
	 * @methodName		: importExcelFile
	 * @description		: 导入组织机构对象数据Excel文件
	 * @see {@link OrgnizationManService#importExcelFile}
	 * @history			:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
    @Override
	public List<String> importExcelFile(HttpServletRequest request,
			MultipartFile upfile, Map<String, Object> params){                
		// 输入参数校验
		checkValidForParams(request, "importExcelFile", params);

		if (upfile == null) {
			throw new BaseException(ExceptionCodes.UPLOAD_NULL_FILE);
		}	

        // 获取参数值
        Integer parentId = Integer.valueOf(params.get("parentId").toString());


        // 检查外键属性值      
        checkRefKeys(params, refKeyFields);            

        // 检查数据权限
        if (request != null){
            // 非内部调用
            drs.checkDataRights(request, params, refDrFields, drFields);
            drs.checkDataRights(request, params, drFields);
        }        

		
		// 获取文件名
		String fileName = upfile.getOriginalFilename();
		// 文件输入流
		InputStream in = null;
		// 文件导入过程中产生的错误信息列表
		List<String> errorList = null;
		// 读取Excel文件得到的数据行列表
		List<String[]> dataRows = null;
		// 文件导入产生的组织机构对象列表
		List<Orgnization> itemList = null;   
        Map<Orgnization,String> obj2RowNoMap = null;    
		
		try {
			try {
				in = upfile.getInputStream();
			} catch(Exception e) {
				LogUtil.error(e);
				throw new BaseException(ExceptionCodes.UPLOAD_READFILE_FAILED,e.getMessage());
			}
			
			// Excel文件导入处理类
			ExcelImportHandler excelImportHandler = new ExcelImportHandler();
			// 数据导入对象基类，注意: new必须加上{}，这样可以访问匿名内部类
			BaseImportObj<Orgnization> impObj = new BaseImportObj<Orgnization>() {};
			errorList = impObj.getErrorLogList();
			
			// 设置导入字段定义对象列表
			List<ImpExpFieldDef> fieldList = new ArrayList<ImpExpFieldDef>();
			fieldList.add(new ImpExpFieldDef("orgName", "组织机构名称", 1));
			fieldList.add(new ImpExpFieldDef("orgFullname", "组织机构全称", 0));
			fieldList.add(new ImpExpFieldDef("orgType", "机构类型", 1));
			fieldList.add(new ImpExpFieldDef("leader", "负责人名称", 0));
			fieldList.add(new ImpExpFieldDef("contacts", "联系人", 1));
			fieldList.add(new ImpExpFieldDef("phoneNumber", "联系电话", 1));
			fieldList.add(new ImpExpFieldDef("email", "Email", 0));
			fieldList.add(new ImpExpFieldDef("address", "地址", 1));
			fieldList.add(new ImpExpFieldDef("zipcode", "邮编", 0));
			fieldList.add(new ImpExpFieldDef("district", "行政区", 1));
			fieldList.add(new ImpExpFieldDef("districtLevel", "行政级别", 0));
			fieldList.add(new ImpExpFieldDef("remark", "备注", 0));
			fieldList.add(new ImpExpFieldDef("parentOrgName", "父组织机构名称", 1));
			impObj.setFieldList(fieldList);                        

            // 导入枚举值标题名数组
            String[] impEnumFields = new String[]{"机构类型","行政级别"};
            // 对应参数类别key
            String[] classKeys = new String[]{"org_type","district_level"};  
			
			// 读取Excel文件Sheet1，一次性读入数据
			dataRows = excelImportHandler.importFile(in, fileName, impObj.getTitleRowNums(), 0);          			
            
            // 获取导入枚举字段列序号与impEnumFields下标的对应关系
			String[] titles = dataRows.get(0);
            Map<Integer,Integer> idxMap = Utility.getColIdxMap(titles,impEnumFields);

			// 导入字段枚举值翻译
			SysParameter spItem = null;
            for(int i = dataRows.size() - 1; i >= 1; i--) {
                String[] dataRow = dataRows.get(i);
                boolean bError = false;
                for(Integer colIdx : idxMap.keySet()){
                    Integer idx = idxMap.get(colIdx);
                    String dataCell = dataRow[colIdx].trim();
                    String classKey = classKeys[idx];
                    if (!dataCell.isEmpty()){
                        spItem = sps.getItemByValue(classKey, dataCell);
                        if (spItem != null) {
                            dataRow[colIdx] = spItem.getItemKey();						
                        }else{
                            // 枚举值错误
                            String error = String.format("row[%d]col[%d]：未定义的枚举值:%s",i,colIdx,dataCell);
                            errorList.add(error);
                            bError = true;
                            break;
                        }                    
                    }
                }
                if (bError) {
                    // 移除错误数据行
                    dataRows.remove(i);
                }
            }
			
			// 导入数据行，一次性导入全部数据
			try {
				itemList = impObj.importAllDatas(dataRows);
			}catch(Exception e) {
				errorList.add(e.getMessage());
			}			
			// 汇总异常信息列表，读取阶段的异常日志放置在前部位置
			impObj.insertErrorList(excelImportHandler.getErrorLog());
			if (errorList.size() > 0) {
				return errorList;
			}	
            obj2RowNoMap = impObj.getObj2RowNoMap();

            // 设置参数值
            for (Orgnization item : itemList) {
                item.setParentId(parentId);
            }        

            // 更新导入
            Map<Integer,String> columnIdxMap = impObj.getColumnIdxMap();
            List<String> fieldNameList = new ArrayList<String>(columnIdxMap.values());
            fieldNameList.add("orgId");
            fieldNameList.add("parentId");
            
            for (int i = 0; i < itemList.size(); i++) {
                Orgnization item = itemList.get(i);
                try{
                    flushItem(request,item,fieldNameList);
                }catch(Exception e) {
				    errorList.add(impObj.getObj2RowNoMap().get(item) + ":" + e.getMessage());
			    }	
            }

			// 最后输出异常信息列表
			return errorList;
		} catch(Exception e) {
			// 传递异常
			throw new RuntimeException(e);
		} finally {
			// 关闭in文件流
			FileUtil.closeStream(in);
		}
    }            

	/**
	 * 
	 * @methodName		: exportExcelFile
	 * @description	    : 根据查询条件导出组织机构对象数据Excel文件
	 * @see {@link OrgnizationManService#exportExcelFile}
     * @history		:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks                   
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
    @Override
	public void exportExcelFile(HttpServletRequest request,HttpServletResponse response,
			Map<String,Object> params){

	    List<Orgnization> itemList = null;
        if (request != null) {
            List<Integer> orgIdList = drs.getQueryDrList(request,"orgId");
            if (params.containsKey("orgIdList")){
                List<Integer> orgIdList2 = (List<Integer>)params.get("orgIdList"); 
                orgIdList = drs.mergeDrIdList(orgIdList,orgIdList2);
                params.put("orgIdList",orgIdList);
            }
        }    
		
		// 根据查询条件params，查询数据库，获取组织机构对象列表
		itemList = orgnizationDao.selectItems(params);
		if (itemList.size() == 0) {
			throw new BaseException(ExceptionCodes.EXPORT_FILE_NO_DATA);
		}
		
		// 构造导出标题列表
		List<ImpExpFieldDef> fieldList = new ArrayList<ImpExpFieldDef>();
		fieldList.add(new ImpExpFieldDef("orgId","组织ID",0));
		fieldList.add(new ImpExpFieldDef("orgName","组织机构名称",0));
		fieldList.add(new ImpExpFieldDef("orgFullname","组织机构全称",0));
		fieldList.add(new ImpExpFieldDef("orgType","机构类型",0));
		fieldList.add(new ImpExpFieldDef("leader","负责人名称",0));
		fieldList.add(new ImpExpFieldDef("contacts","联系人",0));
		fieldList.add(new ImpExpFieldDef("phoneNumber","联系电话",0));
		fieldList.add(new ImpExpFieldDef("email","Email",0));
		fieldList.add(new ImpExpFieldDef("address","地址",0));
		fieldList.add(new ImpExpFieldDef("zipcode","邮编",0));
		fieldList.add(new ImpExpFieldDef("district","行政区",0));
		fieldList.add(new ImpExpFieldDef("districtLevel","行政级别",0));
		fieldList.add(new ImpExpFieldDef("parentId","父组织ID",0));
		fieldList.add(new ImpExpFieldDef("remark","备注",0));
		fieldList.add(new ImpExpFieldDef("parentOrgName","父组织机构名称",0));
		fieldList.add(new ImpExpFieldDef("parentOrgFullname","父组织机构全称",0));

		// 使用导出类
		BaseExportObj expObj = new BaseExportObj();
		// 设置标题数据
		expObj.setTitles(fieldList);
		// 输出标题行
		String[] arrTitles = expObj.exportTitleList();
		// 输出导出数据行
		List<String[]> dataRowList = expObj.exportDataList(itemList);
		
        // 导出枚举值标题名数组
        String[] expEnumFields = new String[]{"机构类型","行政级别"};
        // 对应参数类别key
        String[] classKeys = new String[]{"org_type","district_level"};  

        // 获取导出枚举字段列序号与expEnumFields下标的对应关系
        Map<Integer,Integer> idxMap = Utility.getColIdxMap(arrTitles,expEnumFields);

		// 进行字段值翻译
		String trans = "";
		SysParameter spItem = null;
        String itemValue = "";
		for(String[] dataRow : dataRowList) {
            for(Integer colIdx : idxMap.keySet()){
                Integer idx = idxMap.get(colIdx);
                String dataCell = dataRow[colIdx].trim();
                String classKey = classKeys[idx];
                if (!dataCell.isEmpty()){
                    spItem = sps.getItemByKey(classKey, dataCell, false);
                    if (spItem != null) {
                        dataRow[colIdx] = spItem.getItemValue();						
                    }else{
                        // 枚举值错误
                        dataRow[colIdx] = "";
                    }                    
                }else{
                    dataRow[colIdx] = "";                    
                }
            }
		}
		
		// 导出处理
		// 使用Excel导出处理类
		ExcelExportHandler excelExpHandler = new ExcelExportHandler();
		// 临时文件路径，文件名随机
		String filename = RandomStringUtils.randomAlphanumeric(16) + ".xlsx";
		String excelFilePath = uploadConfig.getUploadPath() + "/" + filename;
		String sheetName = "组织机构记录数据";
        // 导出文件的文件名
        String expFilename = sheetName + ".xlsx";
		try {
			// 生成excel临时文件
			excelExpHandler.exportExcelFile(arrTitles, dataRowList, excelFilePath, sheetName);
			// 调用文件下载方法
			FileUtil.download(response, excelFilePath, expFilename, "application/octet-stream");
		}catch(Exception e) {
			LogUtil.error(e);
			throw new BaseException(ExceptionCodes.EXPORT_EXCEL_FILE_FAILED,e.getMessage());
		}finally {
			if (!debug) {
				// 删除临时文件
				FileUtil.deleteFile(excelFilePath);
			}
		}                

    }

	/**
	 * @methodName			: checkValidForParams
	 * @description			: 输入参数校验
	 * @see {@link BaseService#checkValidForParams}
	 * @history				:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
	@Override
	public void checkValidForParams(HttpServletRequest request, String methodName,
			 Object params) {
		switch(methodName) {
		case "addItem":
		{
			Orgnization item = (Orgnization)params;
			
			// 检查项: 必选字段
	        String[] mandatoryFields = new String[]{"orgName","orgType","contacts","phoneNumber",
	        	"district","parentId"};  
            // 默认值有效字段
            String[] escapeFields = new String[]{"orgCode","orgFullname","orgCategory","leader",
            	"email","address","zipcode","districtLevel","parentId","lon","lat","remark",
            	"operatorName","deleteFlag","createTime","updateTime","parentOrgName",
            	"parentOrgFullname"};  
            ReflectUtil.checkMandatoryFields(item,mandatoryFields,escapeFields);
		}
		break;
        case "addItems":
		{
			List<Orgnization> itemList = (List<Orgnization>)params;
			
			// 检查项: 必选字段
	        String[] mandatoryFields = new String[]{"orgName","orgType","contacts","phoneNumber",
	        	"district","parentId"};  
            // 默认值有效字段
            String[] escapeFields = new String[]{"orgCode","orgFullname","orgCategory","leader",
            	"email","address","zipcode","districtLevel","parentId","lon","lat","remark",
            	"operatorName","deleteFlag","createTime","updateTime","parentOrgName",
            	"parentOrgFullname"};  
            Orgnization defItem = new Orgnization();
            checkMandatoryFields(itemList,defItem,mandatoryFields,escapeFields);
		}        
        break;
		case "editItem":
		{
			Map<String,Object> map = (Map<String,Object>)params;
			
			// 检查项: 
            // 必选字段：key
			Utility.checkKeyFields(map,new String[] {"orgId"});
		}
		break;
		case "updateItems":
		{
			Map<String,Object> map = (Map<String,Object>)params;
			
			// 检查项: 
            // 可选字段：至少一个修改字段
			Utility.checkOpKeyFields(map,new String[] {"zipcode","district","districtLevel",
				"remark","operatorName"});
            // 可选字段：至少一个条件字段
			Utility.checkOpKeyFields(map,new String[] {"parentId","orgIdList"});
		}
		break;
		case "deleteItem":
		{
			Map<String,Object> map = (Map<String,Object>)params;
			
			// 检查项: 
            // 必选字段：key
			Utility.checkKeyFields(map,new String[] {"orgId"});
		}
		break;
		case "deleteItems":
		{
			Map<String,Object> map = (Map<String,Object>)params;
			
			// 检查项: 
            // 可选字段：至少一个条件字段
			Utility.checkOpKeyFields(map,new String[] {"orgIdList","parentId"});
		}
		break;
		case "getItem":
		{
			Map<String,Object> map = (Map<String,Object>)params;
			
			// 检查项: 
            // 必选字段：key
			Utility.checkKeyFields(map,new String[] {"orgId"});
		}
		break;
		case "importExcelFile":
		{
			Map<String,Object> map = (Map<String,Object>)params;
			
			// 检查项: 
            // 必选字段：约定导入参数字段
			Utility.checkKeyFields(map,new String[] {"parentId"});
		}
		break;        
		default:
			break;
		}
	}

	/**
	 * 
	 * @methodName		: checkKey
	 * @description	    : 检查键值的有效性
     * @see {@link BaseService#checkKey}
	 * @history		    : 
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks                   
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */   
    @Override     
    public Object checkKey(String keyPropName, Object propValue) {
        Object item = null;
        // 检查属性值为null的情况
        super.checkKey(keyPropName, propValue);

        switch(keyPropName){
            // 主键属性
            case "orgId":
                item = ics.getObjById("Orgnization",propValue);
                break;
            // 外键属性
            case "parentId":
                if(!propValue.equals(0)){
                    item = ics.getObjById("Orgnization",propValue);
                }
                break;
            default:
                break;
        }
        return item;
    }   

	/**
	 * 
	 * @methodName      : fillRefValue
	 * @description     : 填充实体对象引用属性值
	 * @see {@link BaseService#fillRefValue}
	 * @history		:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks                   
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
    @Override
	public <T> void fillRefValue(T item2) {
		
	}

	/**
	 * 
	 * @methodName	: checkUnique
	 * @description : 检查属性值的唯一性
	 * @see {@link BaseService#checkUnique}
	 * @history		:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks                   
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
    @Override
	public void checkUnique(String propName, Object propValue) {
		switch(propName){
            case "orgName":
            {
                // 获取对象
                Object obj = ics.getObjByUniqueKey("Orgnization",propName,propValue);
                if (obj != null){
                    // 对象已存在
                    throw new BaseException(ExceptionCodes.OBJECT_ALREADY_EXISTS,getPrompt(propName,propValue));
                }
            }
                break;
            default:
                break;
        }
	}    

	/**
	 * 
	 * @methodName	: checkEnum
	 * @description : 检查属性值的枚举类型有效性
	 * @see {@link BaseService#checkEnum}
	 * @history		:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks                   
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
    @Override
	public void checkEnum(String propName, Object propValue) {
		switch(propName){
            case "orgType":
                EOrgType.getTypeByCode(Integer.valueOf(propValue.toString()));
                break;
            case "districtLevel":
                EDistrictLevel.getTypeByCode(Integer.valueOf(propValue.toString()));
                break;
            default:
                break;
        }
	}

	/**
	 * 
	 * @methodName		: getRefId
	 * @description	: 获取引用对象ID
	 * @see {@link BaseService#getRefId}
	 * @history		:
	 * ------------------------------------------------------------------------------
	 * date			version		modifier		remarks                   
	 * ------------------------------------------------------------------------------
	 * 2024/01/14	1.0.0		sheng.zheng		初版
	 *
	 */
    @Override
	public Object getRefId(String propName,Object oValue) {
        Object objId = null;
		switch(propName){
            case "parentOrgName":
                objId = ics.getObjIdByName("Orgnization","parentOrgName",oValue);
                break;
            default:
                break;
        }

		return objId;
	} 
}